package com.group9.handinhand.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.group9.handinhand.controller.form.CommunityCreateForm;
import com.group9.handinhand.controller.form.CommunityUpdateForm;
import com.group9.handinhand.controller.form.CommunityViewForm;
import com.group9.handinhand.service.CommunityService;
import com.group9.handinhand.service.TagService;
import com.group9.handinhand.service.UserService;
import com.group9.handinhand.service.so.CommunityEnums.CommunityPrivacy;
import com.group9.handinhand.service.so.CommunityEnums.RequiredPermissionToSubscribe;
import com.group9.handinhand.service.so.CommunityMemberSO;
import com.group9.handinhand.service.so.CommunityPostSO;
import com.group9.handinhand.service.so.CommunitySO;
import com.group9.handinhand.service.so.CommunityTagSO;
import com.group9.handinhand.service.so.MembershipRequestSO;
import com.group9.handinhand.service.so.TagSO;
import com.group9.handinhand.service.so.UserSO;
import com.group9.handinhand.service.so.UserTagSO;
import com.group9.handinhand.utils.HandInHandWebUtils;

@Controller
public class CommunityController extends AbstractBaseController {
	
	@Autowired
	CommunityService communityService;
	
	@Autowired
	private TagService tagService;
	
	@Autowired
	private UserService userService;
	
	private List<UserSO> moderatorsList;
	
	@RequestMapping(value = "/communities")
	public String communities(HttpServletRequest request, Model model){
		
		UserSO user = getUser();
		if(user == null){
			return "redirect:";
		}
		
		List<CommunitySO> communityList = communityService.getCommunitiesByUser(user);
		model.addAttribute("communityList", communityList);
		return "listCommunities";
	}
	
	@RequestMapping(value = "mobile/communities", method = RequestMethod.POST)
	public ResponseEntity<Map<String, Object>> communitiesMobile(HttpServletRequest request, @RequestBody String body) throws JSONException {
		Map<String, Object> response = new HashMap<String, Object>();
		
		JSONObject json = new JSONObject(body);
		Long userId = json.getLong("userId");
		
		
		UserSO user = userService.getUserById(userId);		
		
		List<CommunitySO> communityList = communityService.getCommunitiesByUser(user);
		response.put("communityList", communityList);
		response.put("auth", HandInHandWebUtils.generateCookieForUser(user.convertToModelObject()));
		response.put("message", "OK");

		return new ResponseEntity<Map<String, Object>>(response, HttpStatus.OK);
	}
	
	/**
	 * Mobile controller for community creation
	 * @param request
	 * @param body
	 * @return
	 * @throws JSONException
	 */
	@RequestMapping(value = "mobile/newCommunity", method = RequestMethod.POST)
	public ResponseEntity<Map<String, Object>> signupMobile(HttpServletRequest request, @RequestBody String body) throws JSONException {
		Map<String, Object> response = new HashMap<String, Object>();

		JSONObject json = new JSONObject(body);
		
		String name = json.getString("name");
		String description = json.getString("description");
		Long userId = json.getLong("userId");
		
		
		CommunitySO community = new CommunitySO();		
		UserSO user = userService.getUserById(userId);
		
		community.setName(name);
		community.setDescription(description);
		RequiredPermissionToSubscribe permission = RequiredPermissionToSubscribe.MODERATOR_PERMISSION;
		community.setPermission(permission);
		CommunityPrivacy privacy = CommunityPrivacy.PUBLIC;
		community.setPrivacy(privacy);
		
		community = communityService.saveCommunity(community, user);
		response.put("community", community);
		response.put("auth", HandInHandWebUtils.generateCookieForUser(user.convertToModelObject()));
		response.put("message", "OK");

		return new ResponseEntity<Map<String, Object>>(response, HttpStatus.OK);
	}
	
	
	@RequestMapping(value = "/newCommunity")
	public String newCommunity(CommunityCreateForm communityCreateForm, HttpServletRequest request, Model model){
		
		communityCreateForm.setCommunity(new CommunitySO());
		
		return "newCommunity";
	}
	
	@RequestMapping(value = "/saveCommunity")
	public String saveCommunity(CommunityCreateForm communityCreateForm, HttpServletRequest request, Model model){
		
		validateNewCommunity(communityCreateForm);
		communityCreateForm.getCommunity().getModerators().add(getUser());
		CommunitySO newCommunity = communityService.saveCommunity(communityCreateForm.getCommunity(), getUser());
		
		List<String> selectedTags = communityCreateForm.getSelectedTagsAsList();
		
		tagService.saveCommunityTags(newCommunity,selectedTags);
		
		return "redirect:/communities/" + newCommunity.getId();
	}
	
	private void validateNewCommunity(CommunityCreateForm communityCreateForm) {
		// TODO Auto-generated method stub
		
	}

	@RequestMapping(value = "/communities/{communityId}")
	public String viewCommunity(@PathVariable Long communityId, CommunityViewForm communityViewForm, HttpServletRequest request, Model model){
		
		CommunitySO community = communityService.getCommunityById(communityId);
		
		UserSO user = getUser();
		if(user == null)
			return "redirect";
		
		CommunityMemberSO communityMemberSO = communityService.getCommunityMemberByCommunityIdAndUserId(communityId, user.getId());	
		CommunitySO moderatedCommunity = communityService.getModeratedCommunityByCommunityIdAndUserId(communityId, user.getId());
		MembershipRequestSO membershipRequest = communityService.getMembershipRequestByCommunityIdAndUserId(communityId, user.getId());
		communityViewForm.setMembershipRequest(membershipRequest);
		communityViewForm.setModeratedCommunity(moderatedCommunity);
		communityViewForm.setCommunity(community);
		communityViewForm.setCommunityMember(communityMemberSO);
		communityViewForm.setWallElementsFromCommunity();
		communityViewForm.setUser(user);
		// Find Community Tags
		List<CommunityTagSO> communityTags = tagService.getCommunityTagsByCommunity(community);
		communityViewForm.setCommunityTags(communityTags);
		
		// Find User Tags
		List<UserTagSO> userTags = tagService.getUserTagsByUser(user);
		communityViewForm.setUserTags(userTags);
		// Find Communities From User Tags
		ArrayList<Object> commList = new ArrayList<Object>();
		communityViewForm.setCommList(commList);
		for(int i=0; i<userTags.size();i++){
		commList.addAll(communityService.getCommunitiesByTag(userTags.get(i)));
		}
		// Exclude Already Member Communities from above found
		List<CommunitySO> communityList = communityService.getCommunitiesByUser(user);
		communityList.add(communityService.getCommunityById(communityId));
		model.addAttribute("communityList", communityList);
		
		for(int i=0; i<communityList.size();i++)
		{
		commList.remove(communityList.get(i));
		}
		
		communityService.getCommunityRecommendations(community, user);

		
		return "viewCommunity";
	}
	
	@RequestMapping(value = "/communities/{communityId}/post")
	public String post(@PathVariable Long communityId, CommunityViewForm communityViewForm, HttpServletRequest request, Model model){
		
		String post = communityViewForm.getPost();
		
		System.out.println(post);
		
//		CommunitySO community = communityService.getCommunityById(communityId);
		UserSO user = getUser();
		
		CommunityPostSO communityPost;
//		if(community != null && user != null)	
			communityPost = communityService.saveCommunityPost(communityId, user.getId(), post);
		
		return "redirect:/communities/" + communityId;
	}
	@RequestMapping(value = "/communities/{communityId}/joincommunity")
	public String addMemberToCommunity(@PathVariable Long communityId, CommunityViewForm communityViewForm, HttpServletRequest request, Model model){
		
		UserSO user = getUser();
		CommunitySO community=communityService.getCommunityById(communityId);
		if(user == null){
			return "redirect:";
		}
		communityService.saveCommunityMember(community, user);

		return "redirect:/communities/" + communityId;
	}
	
	@RequestMapping(value = "/communities/{communityId}/editCommunity")
	public String editCommunity(@PathVariable Long communityId, CommunityUpdateForm communityUpdateForm, HttpServletRequest request, Model model){
		
		CommunitySO community = communityService.getCommunityById(communityId);
		
		if(community != null){
			communityUpdateForm.setCommunity(community);
			List<TagSO> selectedTags = tagService.getTagsByRelatedCommunityId(communityId);
			moderatorsList = communityService.getModeratorsByCommunityId(communityId);
			communityUpdateForm.setSelectedTagsFromList(selectedTags);
		}

		return "updateCommunity";
	}
	
	@RequestMapping(value = "/communities/{communityId}/updateCommunity", method = RequestMethod.POST)
	public String updateCommunity(@PathVariable Long communityId, CommunityUpdateForm communityUpdateForm, HttpServletRequest request, HttpServletResponse response,  Model model)  {	
		
		CommunitySO community = communityUpdateForm.getCommunity();
		
		for(UserSO so : moderatorsList)
		{
			community.getModerators().add(so);
		}
		
		System.out.println("----------------------------------  " + community.getId());;
		
		community.setId(communityId);
		
		communityService.updateCommunity(community);
		List<String> selectedTags = communityUpdateForm.getSelectedTagsAsList();
		
		tagService.saveCommunityTags(community,selectedTags);	
				
		return "redirect:/communities/" + communityId + "/editCommunity";
	}
	
	@RequestMapping(value = "/communities/{communityId}/sendmembership")
	public String sendMembership(@PathVariable Long communityId, HttpServletRequest request, Model model ) {
		
		UserSO user = getUser();
		CommunitySO community =communityService.getCommunityById(communityId);
		if(user != null) {
			communityService.saveMembershipRequest(community, user);	
		}
		
		return "redirect:/communities/" + communityId;
	}
	
	@RequestMapping(value = "/communities/{communityId}/membershiprequests")
	public String membershipRequest(@PathVariable Long communityId, HttpServletRequest request, Model model ) {
		ArrayList<MembershipRequestSO> membershipRequestList = new ArrayList<MembershipRequestSO>();
		UserSO user = getUser();	
		if(user != null) {
			membershipRequestList = communityService.getMembershipRequests(communityId);
		}
		model.addAttribute("membershipRequestList", membershipRequestList);
		model.addAttribute("communityId", communityId);
		return "viewMembershipRequests";
	}
	
	@RequestMapping(value = "/communities/{communityId}/acceptmembership/{userId}")
	public String acceptMembership(@PathVariable Long communityId, @PathVariable Long userId ,HttpServletRequest request, Model model ) {
		
		UserSO user = userService.getUserById(userId);
		CommunitySO community=communityService.getCommunityById(communityId);
		if(user == null){
			return "redirect:";
		}
		communityService.saveCommunityMember(community, user);
		communityService.deleteMembershipRequest(communityId, userId);
		
		return "redirect:/communities/" + communityId + "/membershiprequests";
	}
	
	@RequestMapping(value = "/communities/{communityId}/rejectmembership/{userId}")
	public String rejectMembership(@PathVariable Long communityId, @PathVariable Long userId ,HttpServletRequest request, Model model ) {
		
		UserSO user = userService.getUserById(userId);
		CommunitySO community=communityService.getCommunityById(communityId);
		if(user == null){
			return "redirect:";
		}
		communityService.deleteMembershipRequest(communityId, userId);
		
		return "redirect:/communities/" + communityId + "/membershiprequests";
	}
}
